home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 145
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan).7z
/
Gekkan Dennou Club - 2000.6 Vol. 145 (Japan) (Track 1).bin
/
games
/
spassion
/
source.lzh
/
SOURCE
/
SHOT.C
< prev
next >
Wrap
Text File
|
2000-03-31
|
17KB
|
644 lines
/*
#include <stdio.h>
#include <iocslib.h>
*/
#include <XSP2lib.H>
#include "SPASSION.H"
#include "PLAYER.H"
#include "SHOT.H"
#include "PRIORITY.H"
#include "BG.H"
#include "SOUND.H"
#include "SUB.H"
#ifndef NULL
#define NULL ((void *) 0)
#endif
#define X_MIN (16)
#define X_MAX (16+255)
#define Y_MIN (16)
#define Y_MAX (16+255)
/* ショット用のリスト */
#define SHOT_MAX 100
static SHOT shot[SHOT_MAX];
short MakeConcentShot1( PLAYER *, short );
short MakeConcentShot2( PLAYER *, short );
short MakeConcentShot3( PLAYER *, short );
short MoveConcentShot1( SHOT * );
short MoveConcentShot2( SHOT * );
short MoveConcentShot3( SHOT * );
short MakeDiffShot1( PLAYER *, short );
short MakeDiffShot2( PLAYER *, short );
short MakeDiffShot3( PLAYER *, short );
short MoveDiffShot1( SHOT * );
short MoveDiffShot2( SHOT * );
short MoveDiffShot3( SHOT * );
short MakeChargeShot( PLAYER *, short );
short MoveChargeShot( SHOT * );
short MakeOptionShot( PLAYER *, short );
short MoveOptionShot( SHOT * );
/*
Concentration 集中
Diffusion 拡散
*/
short con1_pt[]={0x44,-1}; /* 前方集中lev1 */
short con2_pt[]={0x45,-1}; /* 前方集中lev2 */
short con3_pt[]={0x00,-1}; /* 前方集中lev3 ツインレーザー */
short diff1_pt[]={0x46,-1}; /* 拡散lev1 前後攻撃 */
short diff2_pt[]={4,5,6,7,8,9,10,11,12,13,-1}; /* 拡散lev2 リップルレーザー */
short diff3_pt[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, /* 拡散lev3 ブーメラン */
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,-1};
short charge_shot_pt[]={14,-1};
short opt1_shot_pt[]={0x30,0x31,0x32,0x33,-1};
short opt2_shot_pt[]={0x40,0x41,0x42,0x43,-1};
HIT_XY con1_bghit[] ={ 1,1,-1,-1};
HIT_XY con2_bghit[] ={ 2,2-1,-1};
HIT_XY con3_bghit[] ={ 6,8,14,8,22,8,30,8,-1,-1};
HIT_XY diff1_bghit[]={ 1,1,-1,-1};
HIT_XY diff2_bghit[]={2,2, 3,4, 3,6, 4,8, 5,12, 6,16, 6,20, 6,24, 6,28, 6,32, -1,-1};
HIT_XY diff3_bghit[]={2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,-1,-1};
HIT_XY charge_bghit[]={32,16,-1,-1};
HIT_XY opt1_bghit[]={6,2,-1,-1};
HIT_XY opt2_bghit[]={6,3,-1,-1};
HIT_XY con1_hit[] ={ 5,5,-1,-1};
HIT_XY con2_hit[] ={ 8,8-1,-1};
HIT_XY con3_hit[] ={ 8,10,16,10,24,10,32,10,-1,-1};
HIT_XY diff1_hit[]={ 4,3,-1,-1};
HIT_XY diff2_hit[]={2,2, 3,4, 3,6, 4,8, 5,12, 6,16, 6,20, 6,24, 6,28, 6,32, -1,-1};
HIT_XY diff3_hit[]={8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,-1,-1};
HIT_XY charge_hit[]={32,16,-1,-1};
HIT_XY opt1_hit[]={8,2,-1,-1};
HIT_XY opt2_hit[]={8,3,-1,-1};
SHOTINFO shot_info[SHOT_TYPES][POW_LEVELS]={
/*pow, pt, info, hit, interval,penetration, func_shot_make, func_shot_move, sd_no*/ /*shot_type*/
{ /* 前方集中 */
{ 3, con1_pt, 0x0200, con1_hit, 6, 0, MakeConcentShot1, MoveConcentShot1, SE_PLAYER_SHOT1 }, /* 0 */
{ 3, con2_pt, 0x0200, con2_hit, 6, 0, MakeConcentShot2, MoveConcentShot2, SE_PLAYER_SHOT1 }, /* 0 */
{ 2, con3_pt, 0x0200, con3_hit, 8, 1, MakeConcentShot3, MoveConcentShot3, SE_PLAYER_SHOT3 }, /* 0 */
},
{ /* 拡散 */
{ 2, diff1_pt, 0x0300, diff1_hit , 6, 0, MakeDiffShot1, MoveDiffShot1, SE_PLAYER_SHOT1 }, /* 1 */
{ 1, diff2_pt, 0x0200, diff2_hit, 12, 1, MakeDiffShot2, MoveDiffShot2, SE_PLAYER_SHOT2 }, /* 1 */
{ 1, diff3_pt, 0x0200, diff3_hit, 12, 1, MakeDiffShot3, MoveDiffShot3, SE_PLAYER_SHOT1 }, /* 1 */
}
};
/* 溜め撃ち */
SHOTINFO charge_shot_info={
3, charge_shot_pt, 0x0400, charge_hit, 0, 1, MakeChargeShot, MoveChargeShot, SE_PLAYER_SHOT4
};
/*オプションの弾*/
SHOTINFO opt_shot_info[SHOT_TYPES]={
/*pow, pt, info, hit,interval,penetration, func_shot_make, func_shot_move, sd_no*/ /*shot_type*/
/* 防御型 */
{ 2, opt1_shot_pt, 0x0200, opt1_hit, 30, 0, MakeOptionShot, MoveOptionShot, SE_PLAYER_SHOT1 }, /* 0 */
/* 攻撃型 */
{ 3, opt2_shot_pt, 0x0200, opt2_hit, 20, 0, MakeOptionShot, MoveOptionShot, SE_PLAYER_SHOT1 } /* 1 */
};
void InitShot0( void )
{
short i,j,k;
for(i=0;i<2;i++){ /* ショットの種類 */
for(j=0;j<3;j++){ /* ショットのレベル */
for(k=0;shot_info[i][j].pt[k]!=-1;k++){
if( (i==0 && j==2) || (i==1 && j==1) )
shot_info[i][j].pt[k]+=obj_shot_b;
else
shot_info[i][j].pt[k]+=obj_shot;
}
}
}
for(k=0;charge_shot_info.pt[k]!=-1;k++)
charge_shot_info.pt[k]+=obj_shot_b;
for(i=0;i<2;i++){
for(k=0;opt_shot_info[i].pt[k]!=-1;k++){
opt_shot_info[i].pt[k]+=obj_shot;
}
}
}
void InitShot( void )
{
short i;
shot_top = NULL;
shot_free = shot;
/* ショットデータの初期化 */
for( i = 0; i < SHOT_MAX; i++ )
shot[i].next = &shot[i + 1];
shot[SHOT_MAX - 1].next = NULL;
}
/*
* 生成
*/
/* 前方集中レベル1 */
static short MakeConcentShot1( PLAYER *pl, short num )
{
SHOTINFO *sh_info=&shot_info[0][0];
SHOT *shot;
shot=MakeShot(10*DOT_RATE,0,sh_info);
shot->player = pl;
shot->lx = pl->lx+4*DOT_RATE;
shot->ly = pl->ly+1*DOT_RATE;
SetSE( sh_info->sd_no ); /* 効果音 */
return TRUE;
}
/* 前方集中レベル2 */
static short MakeConcentShot2( PLAYER *pl, short num )
{
SHOTINFO *sh_info=&shot_info[0][1];
SHOT *shot;
shot=MakeShot(vx_tbl[29][64-4],vy_tbl[29][64-4],sh_info);
shot->player = pl;
shot->lx = pl->lx+4*DOT_RATE;
shot->ly = pl->ly+1*DOT_RATE;
shot=MakeShot(vx_tbl[29][64+4],vy_tbl[29][64+4],sh_info);
shot->player = pl;
shot->lx = pl->lx+4*DOT_RATE;
shot->ly = pl->ly+1*DOT_RATE;
shot=MakeShot(vx_tbl[29][64],vy_tbl[29][64],sh_info);
shot->player = pl;
shot->lx = pl->lx+4*DOT_RATE;
shot->ly = pl->ly+1*DOT_RATE;
SetSE( sh_info->sd_no ); /* 効果音 */
return TRUE;
}
/* 前方集中レベル3(ツインレーザー) */
static short MakeConcentShot3( PLAYER *pl, short num )
{
SHOTINFO *sh_info=&shot_info[0][2];
SHOT *shot;
if( !player->laser[0] ){ /*レーザーが出てなければ*/
shot=MakeShot(10*DOT_RATE,0,sh_info);
shot->player = pl;
shot->lx = pl->lx;
shot->ly = pl->ly;
shot->box.x1=shot->box.x2 = pl->x;
shot->box.y1=shot->box.y2 = pl->y-8;
shot->old_box.x1=shot->old_box.x2 = pl->x;
shot->old_box.y1=shot->old_box.y2 = pl->y-8;
shot->box.color=0xFF;
shot->old_box.color=0;
shot->arg = 0;
pl->laser[0]=1;
}
if( !player->laser[1] ){
shot=MakeShot(10*DOT_RATE,0,sh_info);
shot->player = pl;
shot->lx = pl->lx;
shot->ly = pl->ly;
shot->box.x1=shot->box.x2 = pl->x;
shot->box.y1=shot->box.y2 = pl->y+8;
shot->old_box.x1=shot->old_box.x2 = pl->x;
shot->old_box.y1=shot->old_box.y2 = pl->y+8;
shot->box.color=0xFF;
shot->old_box.color=0;
shot->arg = 1;
pl->laser[1]=1;
SetSE( sh_info->sd_no ); /* 効果音 */
}
return TRUE;
}
/* 拡散レベル1 */
static short MakeDiffShot1( PLAYER *pl, short num )
{
SHOTINFO *sh_info=&shot_info[1][0];
SHOT *shot;
shot=MakeShot(vx_tbl[29][64],vy_tbl[29][64],sh_info);
shot->player = pl;
shot->lx = pl->lx+4*DOT_RATE;
shot->ly = pl->ly+1*DOT_RATE;
shot=MakeShot(vx_tbl[29][192],vy_tbl[29][192],sh_info);
shot->player = pl;
shot->lx = pl->lx;
shot->ly = pl->ly+1*DOT_RATE;
shot->info |= 0x4000;
SetSE( sh_info->sd_no ); /* 効果音 */
return TRUE;
}
/* 拡散レベル2(リップル) */
static short MakeDiffShot2( PLAYER *pl, short num )
{
SHOTINFO *sh_info=&shot_info[1][1];
SHOT *shot;
shot=MakeShot(vx_tbl[25][64],vy_tbl[25][64],sh_info);
shot->player = pl;
shot->lx = pl->lx;
shot->ly = pl->ly;
shot=MakeShot(vx_tbl[25][192],vy_tbl[25][192],sh_info);
shot->player = pl;
shot->lx = pl->lx;
shot->ly = pl->ly;
SetSE( sh_info->sd_no ); /* 効果音 */
return TRUE;
}
/* 拡散レベル3(カッター) */
static short MakeDiffShot3( PLAYER *pl, short num )
{
SHOTINFO *sh_info=&shot_info[1][2];
SHOT *shot;
short j;
for(j=0;j<256;j+=32){
shot=MakeShot(vx_tbl[29][j],vy_tbl[29][j],sh_info);
shot->player = pl;
shot->lx = pl->lx;
shot->ly = pl->ly;
}
SetSE( sh_info->sd_no ); /* 効果音 */
return TRUE;
}
/* 溜め撃ち */
static short MakeChargeShot( PLAYER *pl, short num )
{
SHOTINFO *sh_info=&charge_shot_info;
SHOT *shot;
shot=MakeShot(5*DOT_RATE,0,sh_info);
shot->player = pl;
shot->lx = pl->lx;
shot->ly = pl->ly;
SetSE( sh_info->sd_no ); /* 効果音 */
return TRUE;
}
/* オプションショット */
static short MakeOptionShot( PLAYER *pl, short num )
{
SHOT *shot;
short type=pl->option_type;
short *pt[2]={opt1_shot_pt,opt2_shot_pt};
int vx[2]={6*DOT_RATE,4*DOT_RATE};
shot=MakeShot(vx[type],0,&opt_shot_info[type]);
shot->player = pl;
shot->lx = pl->option[num].lx;
shot->ly = pl->option[num].ly+( 2*DOT_RATE);
shot->pt_ = pt[type];
return TRUE;
}
/*
* 動き
*/
/* 前方集中レベル1 */
static short MoveConcentShot1( SHOT *shot )
{
short x,y,bg;
shot->x = ((shot->lx += shot->vx) >> 16)-8; /*-8は表示位置をずらすため*/
shot->y = ((shot->ly += shot->vy) >> 16)-8;
if( shot->damage
|| SHOT_X > X_MAX+8 )
return FALSE;
if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
if( bg==ERASE_BG )
BreakBG( x, y );
return FALSE;
}
xsp_set_st( shot );
return TRUE;
}
/* 前方集中レベル2 */
static short MoveConcentShot2( SHOT *shot )
{
short x,y,bg;
shot->x = ((shot->lx += shot->vx) >> 16)-8; /*-8は表示位置をずらすため*/
shot->y = ((shot->ly += shot->vy) >> 16)-8;
if( shot->damage
|| SHOT_X > X_MAX+8 || SHOT_Y < Y_MIN-8 || SHOT_Y > Y_MAX+8 )
return FALSE;
if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
if( bg==ERASE_BG )
BreakBG( x, y );
return FALSE;
}
/*
if( shot->damage
|| SHOT_X > X_MAX+8 || SHOT_Y < Y_MIN-8 || SHOT_Y > Y_MAX+8 )
return FALSE;
*/
xsp_set_st( shot );
return TRUE;
}
/* 前方集中レベル3(ツインレーザー) */
static short MoveConcentShot3( SHOT *shot )
{
extern BOX_PTR *old_box_buf[LASER_BUF_MAX],*box_buf[LASER_BUF_MAX];
extern short box_num,old_box_num;
short x,y;
shot->old_box.x1=shot->box.x1;
shot->old_box.y1=shot->box.y1;
shot->old_box.x2=shot->box.x2;
shot->old_box.y2=shot->box.y2;
if( shot->box.x2 < 256 ){ /* レーザーの端が画面外に出るまで伸びる */
shot->box.x1=shot->player->x-16;
shot->box.x2+=8;
}else{
shot->box.x1+=8;
shot->box.x2+=8;
}
shot->x=(shot->box.x1+shot->box.x2)/2;shot->hit_x=shot->x-shot->box.x1;
shot->box.y1=shot->box.y2=shot->y=shot->player->y-16+shot->arg*16-8;
shot->hit_y=8;
shot->lx=(shot->x+16) << 16;
shot->ly=(shot->y+16) << 16;
x=SHOT_X-16;
for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
if( CheckBGHit(x,y)==ERASE_BG )
BreakBG( x, y );
}
if( shot->old_box.x2 < 0 || shot->old_box.x1 > 255
|| shot->player->state!=PLAYER_ALIVE ){
shot->player->laser[shot->arg] = 0;
old_box_buf[old_box_num++]=&shot->old_box;
old_box_num&=31;
old_box_buf[old_box_num]=(BOX_PTR *)0;
return FALSE;
}
box_buf[box_num++]=&shot->box;
box_num&=31;
box_buf[box_num]=(BOX_PTR *)0;
old_box_buf[old_box_num++]=&shot->old_box;
old_box_num&=31;
old_box_buf[old_box_num]=(BOX_PTR *)0;
return TRUE;
}
/* 拡散レベル1 */
static short MoveDiffShot1( SHOT *shot )
{
short x,y,bg;
shot->x = ((shot->lx += shot->vx) >> 16)-8; /*-8は表示位置をずらすため*/
shot->y = ((shot->ly += shot->vy) >> 16)-8;
if( shot->damage
/* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
|| ((unsigned short)shot->x > 256 + 16) )
return FALSE;
if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
if( bg==ERASE_BG )
BreakBG( x, y );
return FALSE;
}
xsp_set_st( shot );
return TRUE;
}
/* 拡散レベル2(リップル) */
static short MoveDiffShot2( SHOT *shot )
{
short x,y;
short *pt=shot_info[1][1].pt;
HIT_XY *hit=shot_info[1][1].hit;
short anim_num;
shot->x = ((shot->lx += shot->vx) >> 16);
shot->y = ((shot->ly += shot->vy) >> 16);
/* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
if( ((unsigned short)shot->x > 256 + 16) )
/* if( SHOT_X < X_MIN-8 || SHOT_X > X_MAX+8 )*/
return FALSE;
x=SHOT_X-16;
for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
if( CheckBGHit(x,y)==ERASE_BG )
BreakBG( x, y );
}
anim_num=(++shot->anim_count)/4;
if( pt[anim_num] == -1 ){
shot->anim_count--;
anim_num--;
}
shot->pt=pt[anim_num];
shot->hit_x=hit[anim_num].x;
shot->hit_y=hit[anim_num].y;
xobj_set_st( shot );
return TRUE;
}
/* 拡散レベル3(カッター) */
static short MoveDiffShot3( SHOT *shot )
{
short x,y;
short *pt=shot_info[1][2].pt;
short anim_num;
shot->x = ((shot->lx += shot->vx) >> 16)-8; /*-8は表示位置をずらすため*/
shot->y = ((shot->ly += shot->vy) >> 16)-8;
/* (画面右から出た判定と左から出た判定を1回の比較で行っている) */
if( ((unsigned short)shot->x > 256 + 16) || ((unsigned short)shot->y > 256 + 16) )
/* if( SHOT_X < X_MIN-8 || SHOT_X > X_MAX+8 || SHOT_Y < Y_MIN-8 || SHOT_Y > Y_MAX+8 )*/
return FALSE;
x=SHOT_X-16;
for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
if( CheckBGHit(x,y)==ERASE_BG )
BreakBG( x, y );
}
anim_num=(shot->anim_count++)/4;
if( pt[anim_num] == -1 ){
shot->anim_count=0;
anim_num=0;
}
shot->pt=pt[anim_num];
xsp_set_st( shot );
return TRUE;
}
/* 溜め撃ち */
static short MoveChargeShot( SHOT *shot )
{
short x,y;
shot->x = ((shot->lx += shot->vx) >> 16);
shot->y = ((shot->ly += shot->vy) >> 16);
if( SHOT_X > X_MAX+32 )
return FALSE;
x=SHOT_X-16;
for(y=SHOT_Y-shot->hit_y-16;y<SHOT_Y+shot->hit_y-16+8;y+=8){
if( CheckBGHit(x,y)==ERASE_BG )
BreakBG( x, y );
}
xobj_set_st( shot );
return TRUE;
}
/* オプションショット */
static short MoveOptionShot( SHOT *shot )
{
short x,y,bg;
short anim_num;
shot->x = ((shot->lx += shot->vx) >> 16)-8; /*-8は表示位置をずらすため*/
shot->y = ((shot->ly += shot->vy) >> 16)-8;
if( shot->damage
|| SHOT_X > X_MAX+8 )
return FALSE;
if( (bg=CheckBGHit(x=SHOT_X-16,y=SHOT_Y-16))!=NON_BG ){
if( bg==ERASE_BG )
BreakBG( x, y );
return FALSE;
}
anim_num=(shot->anim_count++)/4;
if( shot->pt_[anim_num] == -1 ){
shot->anim_count=0;
anim_num=0;
}
shot->pt=shot->pt_[anim_num];
xsp_set_st( shot );
return TRUE;
}
/* --------------- 弾移動 ----------- */
void MoveShot( void )
{
SHOT *p,*q;
p = shot_top; /* 現在注目しているワーク */
q = NULL; /* 1つ前のワーク(ワーク削除時に必要) */
while( p ){
#ifdef DEBUG
if ( !p->func_shot_move ){
void game_end();
printf("MoveShot 1\n");
key_wait();
game_end(); /* ショットの移動ルーチンがない? */
}
#endif
if ( !( *( p->func_shot_move ) )( p ) ) { /* 弾を移動させる */
p=EraseShot(p);
#if 0
if (q == NULL) { /* リストの一番最初を削除 */
shot_top = p->next;
p->next = shot_free;
shot_free = p;
q = NULL;
p = shot_top;
} else {
q->next = p->next;
p->next = shot_free;
shot_free = p;
p = q->next;
}
#endif
} else { /* 消滅していない時 */
/* q = p;*/
p = p->next;
}
}
}
/*
* 自弾の発射ルーチン
*/
SHOT *MakeShot( int vx, int vy, SHOTINFO *sh_info )
{
SHOT *shot;
/* 空いているか調べる */
if( !shot_free )return FALSE;
/* 空いているのを探す */
shot = shot_free;
shot_free = shot->next;
/* 使っているリストに入れる */
if( shot->next = shot_top ){
shot_top->pre = shot;
}
shot->pre = NULL;
shot_top = shot;
/* 各種設定 */
shot->pt = sh_info->pt[0];
shot->info = sh_info->info | PRIORITY_SHOT;
shot->vx = vx;
shot->vy = vy;
shot->hit_x = sh_info->hit[0].x;
shot->hit_y = sh_info->hit[0].y;
shot->pow = sh_info->pow;
shot->penetration = sh_info->penetration;
shot->damage = 0;
shot->anim_count = 0;
shot->func_shot_move= sh_info->func_shot_move;
return shot;
}
/*
* 弾消滅
*/
SHOT *EraseShot( SHOT *sh )
{
SHOT *next;
next = sh->next;
/* 使っているリストから抜く */
if ( sh->pre ) {
sh->pre->next = sh->next;
if ( sh->next ) sh->next->pre = sh->pre;
} else {
if ( sh->next ) sh->next->pre = 0;
shot_top = sh->next;
}
/* 空いているリストに入れる */
sh->pre = 0;
sh->next = shot_free;
shot_free = sh;
return next;
}